﻿using HCLSMod.NetSocket;
using LModBusRTU;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
using System.Windows.Forms;
using ZLSerialPortBusLib.SerialPortBus;

namespace SY280DRIVER
{
    public partial class FSY280DRIVER : Form
    {
        public SY280CFGINI SY280RunCFG = new SY280CFGINI();

        public ZLSerialPortBase tSerialPort = new ZLSerialPortBase();

        public SY280RunTime tSY280RunTime = new SY280RunTime();

        protected JavaScriptSerializer tSerializer = new JavaScriptSerializer();

        public TCPServerSocket tTCPSer { get; private set; } = null;

        public RunLogs tRunLogs { get; private set; } = new RunLogs();

        public FSY280DRIVER()
        {
            InitializeComponent();
            comboBoxPortList.Items.Clear();
            comboBoxPortList.Items.AddRange(SerialPort.GetPortNames());
            if (comboBoxPortList.Items.Count == 1)
                comboBoxPortList.SelectedIndex = 0;
            panelMain.Visible = false;
            if ((comboBoxPortList.Items.Count >0) && (!string.IsNullOrEmpty(SY280RunCFG.SerialPort)))
            {
                for(int i=0;i< comboBoxPortList.Items.Count;i++)
                    if (comboBoxPortList.Items[i].Equals(SY280RunCFG.SerialPort))
                    {
                        comboBoxPortList.SelectedIndex = i;
                        break;
                    }
            }
            numericUpDownServerPort.Value = SY280RunCFG.ServerPort;
            checkBoxAutoStar.Checked = SY280RunCFG.AutoStar;
            StatusLabel设备在线.Text = "设备离线";
            lbDigitalMeterSetValue.Value = 0;
            lbKnobSetValue.Value = 0;
            labelSY280Status.Text = "电机停止";
            labelSY280Status.ForeColor = Color.Lime;
            tRunLogs.Show();
        }

        public void SaveCFG()
        {
            SY280RunCFG.SerialPort = comboBoxPortList.Text;
            SY280RunCFG.ServerPort = (int)numericUpDownServerPort.Value;
            SY280RunCFG.AutoStar = checkBoxAutoStar.Checked;
        }

        public bool OpenCloseCOM(bool SetValue)
        {
            if (SetValue &&(!tSerialPort.IsOpen))
            {
                if ((comboBoxPortList.Items.Count > 0) && (comboBoxPortList.SelectedIndex >= 0))
                {
                    tSerialPort.OpenCOMPort(comboBoxPortList.Text,9600);
                    tSerialPort.CRCEndian = TCRC16Endian.Little;
                    if (tSerialPort.IsOpen)
                        tSY280RunTime.setSerialPort(tSerialPort);
                    tTCPSer = new TCPServerSocket((int)numericUpDownServerPort.Value);
                    tTCPSer.StartListen();
                    tTCPSer.OnReceive += TTCPSer_OnReceive;
                }
            }
            if ((!SetValue) && tSerialPort.IsOpen)
            {
                tSerialPort.Disconnect();
                if (tTCPSer != null)
                    tTCPSer.StopListen();
                tTCPSer = null;
            }
            SaveCFG();
            return tSerialPort.IsOpen;
        }

        private void TTCPSer_OnReceive(object sender, Socket ClientSocket, ref byte[] RecData)
        {
            if ((RecData!=null)&&(RecData.Length>0))
            {
                string sJSONStr = "";
                try
                {
                    sJSONStr = Encoding.UTF8.GetString(RecData);
                    if (tRunLogs != null)
                        tRunLogs.putLogStr(ClientSocket.ToString()+"==>" + sJSONStr.Trim());
                    RecData = null;
                    Dictionary<string, object>  tDatasContainer = (Dictionary<string, object>)tSerializer.DeserializeObject(sJSONStr);
                    if (getResponFromTCPSer(ref tDatasContainer) &&(tDatasContainer!=null)
                        &&(tDatasContainer.Count>0))
                    {
                        sJSONStr = tSerializer.Serialize(tDatasContainer);
                        RecData = Encoding.UTF8.GetBytes(sJSONStr);
                        if (tRunLogs != null)
                            tRunLogs.putLogStr(ClientSocket.ToString() + "<==" + sJSONStr.Trim()); 
                    }
                }
                catch (Exception ex)
                {
                    RecData = null;
                    if (tRunLogs != null)
                        tRunLogs.putLogStr(ex.Message);
                }

            }
        }

        private void tDeamon_Tick(object sender, EventArgs e)
        {
            if (checkBoxAutoStar.Checked)
                OpenCloseCOM(true);
            if (tSerialPort.IsOpen)
            {
                panelMain.Visible = true;
                buttonStarStop.Text = "关  闭";
                if (tSY280RunTime.IsOnline)
                {
                    panelMain.Enabled = true;
                    StatusLabel设备在线.Text = "设备在线";
                    if (tSY280RunTime.IsRunning)
                    {
                        labelSY280Status.Visible = true;
                        labelSY280Status.Text = "电机运行";
                        labelSY280Status.ForeColor = Color.Red;
                        lbButtonStop.Visible = true;
                        lbButtonStar.Visible = false;
                    }
                    else
                    {
                        labelSY280Status.Text = "电机停止";
                        labelSY280Status.ForeColor = Color.Lime;
                        lbButtonStop.Visible = false;
                        lbButtonStar.Visible = true;
                    }
                    lbKnobSetValue.Visible = true;
                    lbDigitalMeterSetValue.Value = tSY280RunTime.iRunValue;
                    TimeSpan tKnobPass = DateTime.Now - tKnobsLastSet;
                    if (tKnobPass.TotalMilliseconds > 1000)
                    {
                        lbKnobSetValue.Value = tSY280RunTime.iRunValue;
                    }
                }
                else
                {
                    panelMain.Enabled = false;
                    StatusLabel设备在线.Text = "设备离线";
                    lbDigitalMeterSetValue.Value = 0;
                    lbKnobSetValue.Value = 0;
                    labelSY280Status.Visible = false;
                    lbButtonStop.Visible = false;
                    lbButtonStar.Visible = false;
                    lbKnobSetValue.Visible = false;
                }
            }
            else
            {
                buttonStarStop.Text = "启  动";
                panelMain.Visible = false;
            }
        }

        private void FSY280DRIVER_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (tTCPSer != null)
                tTCPSer.StopListen();
            tTCPSer = null;
            tSY280RunTime.CloseAll();
            tSerialPort.CloseAll();
        }

        private void buttonStarStop_Click(object sender, EventArgs e)
        {
            if (!tSerialPort.IsOpen)
            {
                OpenCloseCOM(true);
            }
            else
            {
                OpenCloseCOM(false);
            }
        }

        private bool getResponFromTCPSer(ref Dictionary<string, object> tDatasContainer)
        {
            Dictionary<string, object> tResponDatas = new Dictionary<string, object>();
            if ((tDatasContainer != null) && (tDatasContainer.Count > 0))
            {
                if ((tSY280RunTime != null) && (tSY280RunTime.IsOnline))
                {
                    int iDestTmp = 0;
                    if (tDatasContainer.ContainsKey("RunStatus"))
                    {
                        tResponDatas.Add("RunStatus", tSY280RunTime.IsRunning.ToString());
                        tResponDatas.Add("SetRunValue", tSY280RunTime.iRunValue.ToString());
                        tResponDatas.Add("Error", tSY280RunTime.Error.ToString().Replace("EC_", string.Empty));

                    }
                    if (tDatasContainer.ContainsKey("SetStatus"))
                    {
                        if (int.TryParse(tDatasContainer["SetStatus"].ToString(), out iDestTmp)
                            && ((iDestTmp == 1) || (iDestTmp == 5)))
                        {
                            tResponDatas.Add("SetStatus_OK", tDatasContainer["SetStatus"].ToString());
                            tSY280RunTime.IsRunning = (iDestTmp == 1);
                        }
                        else
                        {
                            tResponDatas.Add("SetStatus_Error", tDatasContainer["SetStatus"].ToString());
                        }
                    }
                    if (tDatasContainer.ContainsKey("SetRunValue"))
                    {
                        if (int.TryParse(tDatasContainer["SetRunValue"].ToString(), out iDestTmp)
                            && (iDestTmp >= 0) && (iDestTmp <=1000))
                        {
                            tResponDatas.Add("SetRunValue_OK", tDatasContainer["SetRunValue"].ToString());
                            tSY280RunTime.iRunValue = iDestTmp ;
                        }
                        else
                        {
                            tResponDatas.Add("SetRunValue_Error", tDatasContainer["SetRunValue"].ToString());
                        }
                    }
                }
                else
                {
                    tResponDatas.Add("RunStatus", "Offline");
                }
                tDatasContainer = tResponDatas;
                return true;
            }
            return false;
        }

        private DateTime tKnobsLastSet { get; set; } = DateTime.Now;

        private void lbKnobSetValue_KnobChangeValue(object sender, LBSoft.IndustrialCtrls.Knobs.LBKnobEventArgs e)
        {

        }

        private void lbKnobSetValue_MouseUp(object sender, MouseEventArgs e)
        {
            tKnobsLastSet = DateTime.Now;
            if (tSY280RunTime.IsOnline)
                tSY280RunTime.iRunValue = (int)lbKnobSetValue.Value;
        }

        private void lbButtonStar_ButtonChangeState(object sender, LBSoft.IndustrialCtrls.Buttons.LBButtonEventArgs e)
        {
            if(e.State== LBSoft.IndustrialCtrls.Buttons.LBButton.ButtonState.Normal)
            {
                if (tSY280RunTime.IsOnline)
                    tSY280RunTime.IsRunning = true;
            }
        }

        private void lbButtonStop_ButtonChangeState(object sender, LBSoft.IndustrialCtrls.Buttons.LBButtonEventArgs e)
        {
            if (e.State == LBSoft.IndustrialCtrls.Buttons.LBButton.ButtonState.Normal)
            {
                if (tSY280RunTime.IsOnline)
                    tSY280RunTime.IsRunning = false;
            }
        }
    }


}
